from account.jie_account_service import JieAccountService
from database.park_location_record_table import ParkLocationRecordTable
from manager.lock_manager import LockManager
from model.park_spider import ParkSpider
from model.park_platform import ParkPlatform
from model.car_number import CarNumber
from model.result import Result
from common.logger import logger
from common.amap import search_first

import datetime
import json
import requests
from Crypto.Cipher import AES
import dateutil.parser as dateutil
import spider_config
import common.http as http
import time


from model.error import (
    ParkSpiderError,
    ParkSpiderErrorCode,
    BannedAccountError,
    TokenExpireError,
)


class JieParkSpider(ParkSpider):
    def platform(self) -> ParkPlatform:
        return ParkPlatform(spider_config.jie_park_id)

    def is_in_park(self, carNumber: CarNumber) -> bool:
        fake_userid = self.getAccount()

        data = {
            "carNo": f"{carNumber.province}-{carNumber.city}{carNumber.number}",
            "userId": fake_userid,
        }

        data = json.dumps(data)

        headers = {
            "Host": "sytgate.jslife.com.cn",
            "Accept": "*/*",
            "Content-Type": "application/json;charset=UTF-8",
            "User-Agent": "JTC/6.0.6 (iPhone; iOS 16.3.1; Scale/3.00)",
        }

        url = "https://sytgate.jslife.com.cn/core-gateway/order/carno/pay/appindex"

        rsp = http.post(
            url,
            proxies=self.getProxy(),
            data=data,
            headers=headers,
            timeout=self.getTimeout(),
        )
        rspJson = rsp.json()

        if rspJson["resultCode"] == "0" and "parkAdditionalInfo" not in rspJson["obj"]:
            return False
        else:
            return True

    def getParkName(self, parkCode: str):
        url = "https://sytgate.jslife.com.cn/core-gateway/member/coupon/queryStoreByParkCode"

        data = {
            "parkCode": parkCode,
        }

        data = json.dumps(data)

        headers = {
            "Host": "sytgate.jslife.com.cn",
            "Content-Type": "application/json;charset=UTF-8",
        }

        rsp = http.post(
            url,
            proxies=self.getProxy(),
            data=data,
            headers=headers,
            timeout=self.getTimeout(),
        )

        try:
            rspJson = rsp.json()
        except Exception as e:
            logger.error(repr(e))
            return ""

        if "data" not in rspJson or not rspJson['data']:
            return ""

        parkName = rspJson["data"]["parkName"]
        parkCode = rspJson["data"]["parkCode"]

        # 如果parkCode是以B0开头
        # if parkCode.startswith("B0"):
        #     logger.info(f"find parkCode {parkCode} is B0")

        with ParkLocationRecordTable(spider_config.jie_park_id) as db:
            db_parkName = db.query_by_code(parkCode)
            if db_parkName:
                parkName = db_parkName
            else:
                gdParkName = search_first(parkName)
                if gdParkName:
                    parkName = f"{parkName}(高德：{gdParkName})" 

        return parkName

    def query(self, carNumber: CarNumber):
        account = self.getAccount()

        if not account:
            raise ParkSpiderError(ParkSpiderErrorCode.JieAccountEmpty)

        result = Result()
        result.platform = self.platform()
        result.car_number = carNumber

        # if not self.is_in_park(carNumber):
        #     return result

        userId = account["userId"]

        with LockManager.instance().get(self.platform().id, userId):
            data = {
                "carNo": f"{carNumber.province}-{carNumber.city}{carNumber.number}",
                "userId": userId,
            }

            data = json.dumps(data)

            headers = {
                "Host": "sytgate.jslife.com.cn",
                "Accept": "*/*",
                "Content-Type": "application/json;charset=UTF-8",
                "User-Agent": "JTC/6.0.6 (iPhone; iOS 16.3.1; Scale/3.00)",
            }

            url = "https://sytgate.jslife.com.cn/core-gateway/order/carno/pay/appindex"

            rsp = http.post(
                url,
                proxies=self.getProxy(),
                data=data,
                headers=headers,
                timeout=self.getTimeout(),
            )

            if rsp.status_code != 200:
                result.error_code = rsp.status_code
                result.message = rsp.text
                result.success = False
                return result

            try:
                rspJson = rsp.json()
            except:
                raise json.JSONDecodeError("捷停车json解析失败", rsp.text, 0)

            logger.debug(f"捷停车查询 {carNumber} 结果:{rspJson['resultCode']}")

            result.error_code = rspJson["resultCode"]
            result.success = rspJson["success"]
            result.message = rspJson["message"] if "message" in rspJson else ""

            if not result.success and (len(result.error_code) == 4):
                raise requests.exceptions.ProxyError(f"捷停车反爬: {result.error_code}")

            if not result.success and (
                result.error_code == "123012"
                or result.error_code == "123011"
                or result.error_code == "120003"
            ):
                logger.error(f"捷停车反爬: {rspJson}")
                raise BannedAccountError(userId)

            if not result.success:
                return result

            if (
                "startTime" not in rspJson["obj"]
                or "endTime" not in rspJson["obj"]
                # or rspJson["obj"]["retmsg"] == "非临时卡"
                or rspJson["obj"]["retmsg"] == "未入场"
                or rspJson["obj"]["startTime"] == rspJson["obj"]["endTime"]
            ):
                result.success = False
                return result

            result.enter_time = dateutil.parse(rspJson["obj"]["startTime"])

            if not result.enter_time or result.enter_time >= datetime.datetime.now():
                result.success = False
                return result

            result.price = rspJson["obj"]["totalFee"]
            result.park_name = self.getParkName(rspJson["obj"]["parkCode"])

            logger.debug(f"捷停车查询 {carNumber} 结果:{result}")

            return result
